package org.wbd.pklib.db.logic;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.wbd.pklib.db.Book;
import org.wbd.pklib.db.DataBaseSession;

/**
 * Signeton udostepniajacy obsluge operacji zwiazanych z ksiazkami w bazie danych
 */
public class BookLogic {
	private SessionFactory sessionFactory;
	static private BookLogic bookLogic= null;
	String[] category = {"Dramat", "Fantasy", "Horror", "Komedia", "Kryminał", "Okruchy życia", "Przygodowa", "Satyra",
			"Parodia", "Romans", "Science fiction", "Sport", "Wosjko", "Literatura Faktu", "Literatura Naukowa"};
	
	private BookLogic(){
		sessionFactory = DataBaseSession.getInstance().getSessionFactory();
		
	};
	
	  /**
	    * Zwraca instancje singletona
	    */
	static public BookLogic getInstance(){
		if (bookLogic == null){
			bookLogic = new BookLogic();
		}
		return bookLogic;
	}
	
	  /**
	    * Dodaje ksiazke do bazy danych
	    */
	public LogicRespond addBook(Book book){
		
		if ( !checkIsbn(book.getIsbn()).isSuccesful()){
			return checkIsbn(book.getIsbn());
		}
		
		try {
			Session session = sessionFactory.openSession();
			session.beginTransaction();
			
			
			session.save(book);
			session.getTransaction().commit();
			session.close();	
			return new LogicRespond("Książka dodana", true);
		} catch (Exception e) {
			return new LogicRespond("Książka juz istnieje", false);
		}		
	}

	  /**
	    * Sprawdza czy isbn jest poprawny. 
	    */
	public LogicRespond checkIsbn(String isbn){
		//prepare String
		String[] isbnPart = isbn.split("-");
		String cleanIsbn = new String();
		for (String part : isbnPart){
			cleanIsbn +=part;
		}
		
		//Isbn check
		if (cleanIsbn.length() == 10){
			//ISBN10
			char[] numbers = cleanIsbn.toCharArray();
			int controlSum = 0;
			for (int i=0; i<numbers.length-1 ; i++){
				try {
					controlSum += (i + 1) * Integer.valueOf(Character.toString(numbers[i])); 
				}
				catch (Exception e){
					return new LogicRespond("Niedozwolone znaki", false);
				}
			}
			controlSum = controlSum % 11;
			int controlNum;
			if (numbers[numbers.length - 1] == 'x' || numbers[numbers.length - 1] == 'x' ) {
				controlNum = 10;
			}
			else {
				controlNum = Integer.valueOf(Character.toString(numbers[numbers.length - 1]));
			}
			if (controlSum  == controlNum ){
				return new LogicRespond("Poprawny isbn 10", true);
			}
			else {
				return new LogicRespond("Niepoprawny isbn 10", false);
			}
		}
		else if (cleanIsbn.length() == 13){
			char[] numbers = cleanIsbn.toCharArray();
			int controlSum = 0;
			for (int i=0; i<numbers.length-1 ; i++){
				try {
					if ((i % 2) != 0 ) { //even
						controlSum += 3 * Integer.valueOf(Character.toString(numbers[i])); 						
					}
					else {
						controlSum += Integer.valueOf(Character.toString(numbers[i])); 							
					}					
				}
				catch (Exception e){
					return new LogicRespond("Niedozwolone znaki", false);
					//bad isbn
				}
			}			
			controlSum = (10 - (controlSum % 10)) % 10 ;
			int controlNum = Integer.valueOf(Character.toString(numbers[numbers.length - 1]));
			if (controlSum  == controlNum ){
				return new LogicRespond("Poprawny isbn 13", true);
			}
			else {				
				return new LogicRespond("Nieoprawny isbn 13", false);
			}
		}
		else{
			return new LogicRespond("Zbyt długi isbn", false);
		}			
	}
	  /**
	    * Znajduje ksiazki wyspecyfikowana przez wzór reprezentowany w obiekcie klasy book
	    */
	public LogicRespond searchBooks(Book book) {

		String bookQuery;

		if ((book.getPublicationYear() != null)
				&& (book.getPublicationYear() != 0)) {
			bookQuery = String
					.format("from Book where isbn like '%%%s%%' and author like '%%%s%%' and title like '%%%s%%' and publicationYear = %d and  publisher like '%%%s%%' ",
							book.getIsbn(), book.getAuthor(), book.getTitle(),
							book.getPublicationYear(), book.getPublisher());
		} else {
			bookQuery = String
					.format("from Book where isbn like '%%%s%%' and author like '%%%s%%' and title like '%%%s%%'  and  publisher like '%%%s%%' ",
							book.getIsbn(), book.getAuthor(), book.getTitle(),
							book.getPublisher());
		}
		
		LogicRespond logicRespond;
		try {
			Session session = sessionFactory.openSession();
			session.beginTransaction();

			List<Object> bookQueryResult = session.createQuery(bookQuery).list();
			logicRespond = new LogicRespond("Found items", false);
			for (Object b: bookQueryResult){
				((Book) b).getItems().toString();
			}
			logicRespond.setResultList(bookQueryResult);

			session.getTransaction().commit();
			session.close();
		} catch (Exception e) {
			logicRespond = new LogicRespond("DB error", false);
		}

		return logicRespond;
	}

	

	
}